#ifndef STRBASE_HPP
#define STRBASE_HPP

#include <time.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>


class StrBase
{
public:

    static void FixSlash(std::string &folder)
    {
            if (folder.back() == '/')
                    folder.pop_back();
            if (folder.back() != '\\')
                    folder.push_back('\\');
    }

    static void SpiltFullPath(std::string &folder, std::string &filename, std::string path)
    {
            std::size_t found = path.find_last_of("/\\");
            folder = path.substr(0, found + 1);
            filename = path.substr(found + 1);
    }

    static void SpiltExtention(std::string &name, std::string &extention, std::string filename)
    {
            std::size_t found = filename.find_last_of(".");
            name = filename.substr(0, found);
            extention = filename.substr(found);
    }

    static void RandomInit()
    {
            srand(time(NULL));
    }

    static char RandomChar()
    {
            static const char alphanum[] =
                    "0123456789"
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    "abcdefghijklmnopqrstuvwxyz";
            return alphanum[rand() % (sizeof(alphanum) - 1)];
    }

    static std::string RandomString(size_t len = 8)
    {
            std::string res = "";
            for (size_t i = 0; i < len; ++i) {
                    res.push_back(RandomChar());
            }
            return res;
    }

    static std::string TimeString(unsigned int bSeg = 0)
    {
            time_t rawtime;
            time(&rawtime);
            struct tm *timeinfo = localtime(&rawtime);
            const size_t l = 20;
            char buffer[l];
            switch (bSeg)
            {
            case 1:
                    strftime(buffer, l, "%Y-%m-%d %H:%M:%S", timeinfo);
                    break;
            case 2:
                    strftime(buffer, l, "%Y%m%d_%H%M%S", timeinfo);
                    break;
            default:
                    strftime(buffer, l, "%Y%m%d%H%M%S", timeinfo);
                    break;
            }
            std::string re(buffer);
            return re;
    }

    static std::string ms2str(size_t nms)
    {
            if (nms<1000)
            {
                    char buf[6];
                    sprintf(buf, "%ums", nms);
                    return std::string(buf);
            }

            size_t ns = nms / 1000;
            nms = nms % 1000;

            if (ns<60)
            {
                    char buf[9];
                    sprintf(buf, "%us%ums", ns, nms);
                    return std::string(buf);
            }

            size_t nm = ns / 60;
            ns = ns % 60;

            if (nm<60)
            {
                    char buf[12];
                    sprintf(buf, "%um%us%ums", nm, ns, nms);
                    return std::string(buf);
            }

            size_t nh = nm / 60;
            nm = nm % 60;

            if (nh < 24)
            {
                    char buf[15];
                    sprintf(buf, "%uh%um%us%ums", nh, nm, ns, nms);
                    return std::string(buf);
            }

            size_t nd = nh / 24;
            nh = nh % 24;

            char buf[50];
            sprintf(buf, "%ud%uh%um%us%ums", nd, nh, nm, ns, nms);
            return std::string(buf);
    }

};


#include <locale.h>

class StrBaseW : public StrBase
{
public:
    static std::string ToStd(const std::wstring& ws)
    {
            //string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";

            //setlocale(LC_ALL, "chs");

            const wchar_t* _Source = ws.c_str();
            size_t _Dsize = 2 * ws.size() + 1;
            char *_Dest = new char[_Dsize];
            memset(_Dest, 0, _Dsize);
            wcstombs(_Dest, _Source, _Dsize);
            std::string result = _Dest;
            delete[]_Dest;

            //setlocale(LC_ALL, curLocale.c_str());

            return result;
    }

    static std::wstring ToWide(const std::string& s)
    {
            //setlocale(LC_ALL, "chs");

            const char* _Source = s.c_str();
            size_t _Dsize = s.size() + 1;
            wchar_t *_Dest = new wchar_t[_Dsize];
            wmemset(_Dest, 0, _Dsize);
            mbstowcs(_Dest, _Source, _Dsize);
            std::wstring result = _Dest;
            delete[]_Dest;

            //setlocale(LC_ALL, "C");

            return result;
    }

    static void FixSlash(std::wstring &folder)
    {
            if (folder.back() == L'/')
                    folder.pop_back();
            if (folder.back() != L'\\')
                    folder.push_back(L'\\');
    }

    static void SpiltFullPath(std::wstring &folder, std::wstring &filename, std::wstring path)
    {
            std::size_t found = path.find_last_of(L"/\\");
            folder = path.substr(0, found + 1);
            filename = path.substr(found + 1);
    }

    static void SpiltExtention(std::wstring &name, std::wstring &extention, std::wstring filename)
    {
            std::size_t found = filename.find_last_of(L".");
            name = filename.substr(0, found);
            extention = filename.substr(found);
    }

    static wchar_t RandomChar()
    {
            return wchar_t(StrBase::RandomChar());
    }

    static std::wstring RandomString(size_t len = 8)
    {
            std::string ts = StrBase::RandomString(len);
            return std::wstring(ts.begin(), ts.end());
    }

    static std::wstring TimeString(unsigned int bSeg = 0)
    {
            std::string ts = StrBase::TimeString(bSeg);
            return std::wstring(ts.begin(), ts.end());
    }

};

#endif
